#include <iostream>
using namespace std;


class Data{
public:
    Data(){}
    ~Data(){}

    int getData() const{ return _data; }
private:
    int _data = 10;
};

class MiddleLayer
{
public:
    MiddleLayer(Data * p)
    : _pdata(p)
    {}

    ~MiddleLayer(){
        if(_pdata){
            delete _pdata;
            _pdata = nullptr;
        }
    }

    Data * operator->(){
        return _pdata;
    }

    Data& operator*(){
        return *_pdata;
    }

    // friend class ThirdLayer;

private:
    Data * _pdata;
};

class ThirdLayer{
public:
    ThirdLayer(MiddleLayer * pml)
    :_pml(pml) // 浅拷贝，共同指向同一块堆空间
    {}

    ~ThirdLayer(){
        if (_pml){
            delete _pml;
            _pml = nullptr;
        }
    }

    // 方式1：借助友元声明，太麻烦，不推荐，层越多越乱
    // Data * operator->(){
    //     return (*_ml)._pdata;
    // }

    // 方式2：借助MiddleLayer之前已经完成的箭头与运算符重载
    MiddleLayer& operator->(){
        return *_pml;
    }

    // 一层一层解引用
    MiddleLayer& operator*(){
        return *_pml;
    }

    // 一步到位解引用
    // Data& operator*(){
    //     // return *((*_pml)._pdata); // 需要友元支持
    //     return *((*_pml)); // 不需要友元支持，利用middleLayer的解引用重载
    // }
private:
    MiddleLayer * _pml;
};

void test0(){
    // MiddleLayer ml(new Data());
    // ThirdLayer tl(&ml);
    ThirdLayer tl(new MiddleLayer(new Data));

    // 方式2的本质形式
    // tl.operator->().operator->()->getData()

    // 方式1的本质形式
    cout << tl.operator->()->getData() << endl;
    cout << tl->getData() << endl;

    // 一层一层解引用
    cout << (*(*tl)).getData() << endl;

    // 一步到位解引用
    // cout << (*tl).getData() << endl;

    MiddleLayer * pml = new MiddleLayer(new Data());
    ThirdLayer tl1(pml);
}

int main(void){
    test0();
    return 0;
}

